/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.appschool.dao;


import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

/**
 */
public class GenericDAO<T> {

    private EntityManagerFactory emf = null;

    public EntityManagerFactory getEMF() {
        if (emf == null || !emf.isOpen()) {
            emf = Persistence.createEntityManagerFactory("AppSchoolPU");
        }
        return emf;
    }

    public boolean create(T obj) {
        EntityManager em = getEMF().createEntityManager();
        boolean is = false;
        try {
            em.getTransaction().begin();
            em.persist(obj);
            em.getTransaction().commit();
            is = true;
        } catch (Exception e) {
            is = false;
            em.getTransaction().rollback();
            System.err.println("Erro: " + e.getMessage());
        } finally {
            em.close();
            emf.close();
        }
        return is;
    }

    public boolean update(T obj) {
        EntityManager em = getEMF().createEntityManager();
        boolean is = false;
        try {
            em.getTransaction().begin();
            em.merge(obj);
            em.getTransaction().commit();
            is = true;
        } catch (Exception e) {
            is = false;
            em.getTransaction().rollback();
            System.err.println("Erro: " + e.getMessage());
        } finally {
            em.close();
            emf.close();
        }
        return is;
    }

    public boolean delete(T obj) {
        EntityManager em = getEMF().createEntityManager();
        boolean is = false;
        try {
            em.getTransaction().begin();
            if (!em.contains(obj)) {
                obj = em.merge(obj);
            }
            em.remove(obj);
            em.getTransaction().commit();
            is = true;
        } catch (Exception e) {
            is = false;
            em.getTransaction().rollback();
            System.err.println("Erro: " + e.getMessage());
        } finally {
            em.close();
            emf.close();
        }
        return is;
    }

    public boolean delete(Class<T> classe, Integer id) {
        EntityManager em = getEMF().createEntityManager();
        boolean is = false;
        try {
            em.getTransaction().begin();
            T obj = em.find(classe, id);
            em.remove(obj);
            em.getTransaction().commit();
            is = true;
        } catch (Exception e) {
            is = false;
            em.getTransaction().rollback();
            System.err.println("Erro: " + e.getMessage());
        } finally {
            em.close();
            emf.close();
        }
        return is;

    }

    public T findById(Class<T> classe, Integer id) {
        EntityManager em = getEMF().createEntityManager();
        T obj = null;
        try {
            obj = em.find(classe, id);
        } catch (Exception e) {
            obj = null;
            System.err.println("Erro: " + e.getMessage());
        } finally {
            em.close();
            emf.close();
        }
        return obj;
    }

    public List<T> findAll(String classe, String orderField) {
        EntityManager em = getEMF().createEntityManager();
        List<T> objs = new ArrayList<T>();
        try {
            String jpql = "SELECT obj FROM " + classe + " obj ORDER BY obj." + orderField;
            Query query = em.createQuery(jpql);
            objs = query.getResultList();
        } catch (Exception e) {
            objs = null;
            System.err.println("Erro: " + e.getMessage());
        } finally {
            em.close();
            emf.close();
        }
        return objs;
    }

    public int count(String classe) {
        EntityManager em = getEMF().createEntityManager();
        try {
            String jpql = "SELECT COUNT(obj) FROM " + classe + " AS obj";
            return ((Long) em.createQuery(jpql).getSingleResult()).intValue();
        } catch (Exception e) {
            System.err.println("Erro: " + e.getMessage());
            return 0;
        } finally {
            em.close();
            emf.close();
        }
    }

}